/* Copyright 2018 Intel Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file
 * Avalon Crypto Utilities:
 * secret key generation, * encrypt, and decrypt.
 * These are higher-level utility functions that use AES-256
 * and are implemented with * tcf::skenc functions in skenc.cpp.
 * No OpenSSL-dependent code is present.
 */

#include "crypto_shared.h"
#include "crypto_utils.h"
#include "error.h"
#include "tcf_error.h"
#include "hex_string.h"
#include "utils.h"
#include "skenc.h"

namespace pcrypto = tcf::crypto;


/**
 * Create symmetric encryption key and return hex-encoded key string.
 * Uses AES-GCM 256, which also includes authentication.
 * Key generated is 256 bits represented as a 64 hex digit printable string.
 * Key for use with EncryptData() and DecryptData().
 *
 * @returns AES-GCM-256 key as a hex-encoded string
 */
std::string pcrypto::CreateHexEncodedEncryptionKey() {
    ByteArray enc_key = tcf::crypto::skenc::GenerateKey();
    return ByteArrayToHexEncodedString(enc_key);
}   // pcrypto::CreateHexEncodedEncryptionKey


/**
 * Encrypt the message using given encryption key and return cipher.
 * Uses AES-GCM 256, which also includes authentication.
 * Use symmetric encryption key generated by CreateHexEncodedEncryptionKey().
 * Implemented using pcrypto::skenc::EncryptMessage().
 *
 * @param msg binary data to encrypt
 * @param key symmetric encryption key in a hex-encoded string.
 *            Generated by CreateHexEncodedEncryptionKey()
 * @returns base64 encoded string containing encrypted data
 */
std::string pcrypto::EncryptData(std::string msg, std::string key) {
    ByteArray msg_bytes = StrToByteArray(msg);
    ByteArray key_bytes = tcf::HexStringToBinary(key);
    ByteArray cipher = tcf::crypto::skenc::EncryptMessage(key_bytes,
        msg_bytes);
    return ByteArrayToBase64EncodedString(cipher);
}  // pcrypto::EncryptData


/**
 * Decrypt cipher using given encryption key and return message.
 * Uses AES-GCM 256, which also includes authentication.
 * Use symmetric encryption key generated by CreateHexEncodedEncryptionKey().
 * Implemented using pcrypto::skenc::DecryptMessage().
 *
 * @param cipher encrypted binary data encoded as a base64 string.
 *               Generated by EncryptMessage()
 * @param key    symmetric encryption key in a hex-encoded string.
 *               Generated by CreateHexEncodedEncryptionKey()
 * @returns base64 encoded string containing encrypted data
 */
std::string pcrypto::DecryptData(std::string cipher, std::string key) {
    ByteArray ciphers_bytes = Base64EncodedStringToByteArray(cipher);
    ByteArray key_bytes = tcf::HexStringToBinary(key);
    ByteArray msg = tcf::crypto::skenc::DecryptMessage(key_bytes,
        ciphers_bytes);
    return ByteArrayToStr(msg);
}  // pcrypto::DecryptData
